#!/bin/bash

# Debian 镜像源测速工具 v2.2
# 完整版，包含测速、选择最佳镜像源和更换镜像源功能

# 配置文件路径
lists_tmp=/tmp/lists.conf

# 自然风格配色方案
BG='\033[48;2;30;30;35m'        # 深灰蓝背景
TEXT='\033[38;2;220;220;220m'   # 灰白文本
PRIMARY='\033[38;2;100;180;255m' # 柔和的蓝色
SECONDARY='\033[38;2;120;220;150m' # 柔和的绿色
ACCENT='\033[38;2;255;200;100m'  # 柔和的橙色
ERROR='\033[38;2;255;100;100m'   # 柔和的红色
NC='\033[0m'                    # 重置颜色

# 自然风格边框
BORDER_TOP="┌──────────────────────────────────────────────────────┐"
BORDER_MID="├──────────────────────────────────────────────────────┤"
BORDER_BOT="└──────────────────────────────────────────────────────┘"

# 打印自然风格标题
print_natural_header() {
    clear
    echo -e "${BG}${PRIMARY}${BORDER_TOP}${NC}"
    echo -e "${BG}${PRIMARY}│${NC}${BG}${TEXT}          Debian 镜像源测速工具 v2.2          ${NC}${BG}${PRIMARY}│${NC}"
    echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
}

# 自然风格状态显示
natural_status() {
    local status=$1
    local message=$2
    
    case $status in
        "success") echo -e "${BG}${PRIMARY}│${NC} ${SECONDARY}✓${NC} ${TEXT}$message${NC} ${BG}${PRIMARY}│${NC}" ;;
        "info") echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}ℹ${NC} ${TEXT}$message${NC} ${BG}${PRIMARY}│${NC}" ;;
        "warning") echo -e "${BG}${PRIMARY}│${NC} ${ACCENT}⚠${NC} ${TEXT}$message${NC} ${BG}${PRIMARY}│${NC}" ;;
        "error") echo -e "${BG}${PRIMARY}│${NC} ${ERROR}✗${NC} ${TEXT}$message${NC} ${BG}${PRIMARY}│${NC}" ;;
    esac
}

# 获取当前地区代码
get_region() {
    local region=$(curl -sSL --http2 --compressed 'http://ip-api.com/json/?fields=countryCode' 2>/dev/null | awk -F'"' '{print $4}')
    echo "$region"
}

# 检查root权限
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        natural_status "error" "此脚本需要root权限"
        exit 1
    fi
}

# 安装必要工具
install_tools() {
    if ! command -v bc &>/dev/null; then
        natural_status "info" "正在安装bc计算器工具..."
        apt-get update -qq > /dev/null 2>&1 && apt-get install -y bc > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            natural_status "error" "bc安装失败"
            exit 1
        fi
    fi
}

# 更换镜像源
change_mirror() {
    local best_mirror=$1
    local min_delay=$2
    
    echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}步骤 4/4: ${TEXT}更换镜像源${NC} ${BG}${PRIMARY}│${NC}"
    echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
    
    # 备份当前源
    natural_status "info" "备份当前源为 /etc/apt/sources.list.bak"
    if ! cp /etc/apt/sources.list /etc/apt/sources.list.bak; then
        natural_status "error" "备份失败，请检查权限"
        return 1
    fi

    # 写入新源
    natural_status "info" "写入新的镜像源配置"
    cat > /etc/apt/sources.list <<EOF
deb http://$best_mirror/debian/ bullseye main non-free contrib
deb-src http://$best_mirror/debian/ bullseye main non-free contrib
deb http://$best_mirror/debian-security/ bullseye-security main
deb-src https://$best_mirror/debian-security/ bullseye-security main
EOF

    # 尝试更新
    natural_status "info" "正在更新软件包列表..."
    if apt-get update -qq > /dev/null 2>&1; then
        # 成功情况
        echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
        echo -e "${BG}${PRIMARY}${BORDER_TOP}${NC}"
        echo -e "${BG}${PRIMARY}│${NC}${BG}${TEXT}           镜像源更换已完成            ${NC}${BG}${PRIMARY}│${NC}"
        echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
        natural_status "success" "最佳镜像源: ${SECONDARY}$best_mirror${NC}"
        natural_status "success" "平均延迟: ${SECONDARY}$min_delay ms${NC}"
        natural_status "info" "旧配置已备份为 /etc/apt/sources.list.bak"
        echo -e "${BG}${PRIMARY}${BORDER_BOT}${NC}"
        return 0
    else
        # 失败情况
        natural_status "error" "更新软件包列表失败"
        natural_status "info" "正在恢复备份..."
        if ! cp /etc/apt/sources.list.bak /etc/apt/sources.list; then
            natural_status "error" "恢复备份失败"
            return 1
        fi
        apt-get update -qq > /dev/null 2>&1
        natural_status "success" "备份恢复完成"
        echo -e "${BG}${PRIMARY}${BORDER_BOT}${NC}"
        return 1
    fi
}

# 主程序开始
print_natural_header

# 检查root权限
check_root

# 安装必要工具
install_tools

# 1/4 检测地区
echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}步骤 1/4: ${TEXT}检测地区${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
natural_status "info" "正在查询您的位置..."
region=$(get_region)
if [ -z "$region" ]; then
    natural_status "warning" "无法检测地区，默认使用US"
    region="US"
else
    natural_status "success" "检测到地区代码: ${ACCENT}$region${NC}"
fi
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

# 2/4 获取镜像列表
echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}步骤 2/4: ${TEXT}获取镜像${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

# 定义镜像列表（按地区分组）
cn_mirrors=(
    mirrors.aliyun.com
    mirrors.cloud.tencent.com
    mirrors.163.com
    mirrors.tuna.tsinghua.edu.cn
    mirrors.ustc.edu.cn
)

hk_mirrors=(
    ftp.hk.debian.org
    mirror.xtom.com.hk
)

us_mirrors=(
    ftp.us.debian.org
    ftp.ca.debian.org
    mirrors.ocf.berkeley.edu
)

# 根据地区选择镜像组
case $region in
    CN) 
        natural_status "info" "使用中国大陆镜像列表"
        mirrors=("${cn_mirrors[@]}")
        ;;
    HK|MO)
        natural_status "info" "使用香港/澳门镜像列表"
        mirrors=("${hk_mirrors[@]}")
        ;;
    US|CA)
        natural_status "info" "使用美国/加拿大镜像列表"
        mirrors=("${us_mirrors[@]}")
        ;;
    *)
        natural_status "info" "使用全球镜像列表"
        mirrors=("${cn_mirrors[@]}" "${hk_mirrors[@]}" "${us_mirrors[@]}")
        ;;
esac

mirror_count=${#mirrors[@]}
natural_status "success" "找到 ${ACCENT}$mirror_count${NC} 个镜像"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

# 显示镜像列表
echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}可用镜像 ${TEXT}($mirror_count)${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
printf "${BG}${PRIMARY}│${NC} ${TEXT}%-4s %-40s${NC} ${BG}${PRIMARY}│${NC}\n" "编号" "镜像域名"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

count=1
for mirror in "${mirrors[@]}"; do
    printf "${BG}${PRIMARY}│${NC} ${PRIMARY}%-4d${NC} ${TEXT}%-40s${NC} ${BG}${PRIMARY}│${NC}\n" "$count" "$mirror"
    ((count++))
done
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

# 3/4 测试镜像延迟
echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}步骤 3/4: ${TEXT}测试速度${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
natural_status "info" "正在测试每个镜像(3次ping测试)"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

declare -A avg_delays
total_mirrors=${#mirrors[@]}
current=1

for mirror in "${mirrors[@]}"; do
    echo -e "${BG}${PRIMARY}│${NC} ${SECONDARY}测试中 ${TEXT}$current/$total_mirrors${NC} ${SECONDARY}- ${TEXT}$mirror${NC} ${BG}${PRIMARY}│${NC}"
    echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
    
    delays=()
    echo -ne "${BG}${PRIMARY}│${NC} ${TEXT}结果:${NC} "
    
    for i in {1..3}; do
        delay=$(ping -c 1 -W 2 "$mirror" 2>/dev/null | grep 'time=' | awk -F'time=' '{print $2}' | awk '{print $1}')
        
        if [ -z "$delay" ]; then
            delay="9999"
            echo -ne "${ERROR}超时${NC} "
        else
            if (( $(echo "$delay < 50" | bc -l) )); then
                echo -ne "${SECONDARY}${delay}ms${NC} "
            elif (( $(echo "$delay < 100" | bc -l) )); then
                echo -ne "${PRIMARY}${delay}ms${NC} "
            elif (( $(echo "$delay < 200" | bc -l) )); then
                echo -ne "${ACCENT}${delay}ms${NC} "
            else
                echo -ne "${ERROR}${delay}ms${NC} "
            fi
        fi
        
        delays+=("$delay")
        sleep 0.3
    done
    
    sum=0
    for d in "${delays[@]}"; do
        sum=$(echo "$sum + $d" | bc)
    done
    avg=$(echo "scale=2; $sum / 3" | bc)
    
    avg_delays["$mirror"]=$avg
    echo -e "\n${BG}${PRIMARY}│${NC} ${TEXT}平均延迟: ${ACCENT}${avg}ms${NC} ${BG}${PRIMARY}│${NC}"
    echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
    ((current++))
done

# 显示结果
echo -e "${BG}${PRIMARY}│${NC} ${PRIMARY}测试结果${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
printf "${BG}${PRIMARY}│${NC} ${TEXT}%-4s %-36s %8s${NC} ${BG}${PRIMARY}│${NC}\n" "排名" "镜像域名" "延迟"
echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"

rank=1
for mirror in $(for key in "${!avg_delays[@]}"; do echo "$key ${avg_delays[$key]}"; done | sort -nk2 | awk '{print $1}'); do
    if [ $rank -eq 1 ]; then
        best_mirror="$mirror"
        min_delay="${avg_delays[$mirror]}"
        printf "${BG}${PRIMARY}│${NC} ${SECONDARY}%-4d${NC} ${SECONDARY}%-36s${NC} ${SECONDARY}%8sms${NC} ${BG}${PRIMARY}│${NC}\n" "$rank" "$mirror" "${avg_delays[$mirror]}"
    elif [ $rank -le 5 ]; then
        printf "${BG}${PRIMARY}│${NC} ${PRIMARY}%-4d${NC} ${TEXT}%-36s${NC} ${PRIMARY}%8sms${NC} ${BG}${PRIMARY}│${NC}\n" "$rank" "$mirror" "${avg_delays[$mirror]}"
    else
        printf "${BG}${PRIMARY}│${NC} %-4d ${TEXT}%-36s${NC} %8sms ${BG}${PRIMARY}│${NC}\n" "$rank" "$mirror" "${avg_delays[$mirror]}"
    fi
    ((rank++))
done

echo -e "${BG}${PRIMARY}${BORDER_MID}${NC}"
echo -e "${BG}${PRIMARY}│${NC} ${TEXT}推荐镜像: ${SECONDARY}$best_mirror${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}│${NC} ${TEXT}最佳延迟: ${SECONDARY}$min_delay ms${NC} ${BG}${PRIMARY}│${NC}"
echo -e "${BG}${PRIMARY}${BORDER_BOT}${NC}"

# 4/4 更换镜像源
print_natural_header
change_mirror "$best_mirror" "$min_delay"

# 清理文件
rm -f $lists_tmp

